using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;

public class DrawUV2 : MonoBehaviour
{
    public Mesh mesh;
    public Vector2[] uv;


    public float size = 0.1f;
    public int rect = 100;
    public Vector2Int offset = new Vector2Int(-50, -50);
    public int[] triangles;

    private void OnGUI()
    {
        if (GUILayout.Button("test"))
        {
            OnDrawGizmos1();
        }
    }

    private List<Vector3[]> ls = new List<Vector3[]>();
    public GameObject parefab;
    public Transform parent;
    public Transform cacheParent;

    public List<GameObject> items = new List<GameObject>();
    public List<GameObject> cacheItems = new List<GameObject>();

    public GameObject tempgo;

    void OnDrawGizmos1()
    {
        var meshfilter = tempgo.GetComponent<MeshFilter>();
        meshfilter.sharedMesh = GameObject.Instantiate(mesh);
        uv = meshfilter.mesh.uv;
        Texture2D te2d = (Texture2D)tempgo.GetComponent<Renderer>().sharedMaterial.mainTexture;
        if (te2d != null)
        {
            Sprite sp = Sprite.Create(te2d, new Rect(0, 0, te2d.width, te2d.height), Vector2.zero);
            GameObject.FindObjectOfType<UVContent>().GetComponent<UnityEngine.UI.Image>().sprite = sp;
        }

        for (int i = 0; i < items.Count; i++)
        {
            if (!items[i].Equals(null))
            {
                items[i].SetActive(false);
                items[i].transform.SetParent(cacheParent);
                cacheItems.Add(items[i]);
            }
        }

        items.Clear();
        triangles = mesh.triangles;
        ls.Clear();

        // 获取所有三角形的法线
        Vector3[] normals = mesh.normals;

        Dictionary<Vector3, List<int[]>> groupDic = new Dictionary<Vector3, List<int[]>>();
        List<int[]> nonGroupLs = new List<int[]>();

        for (int i = 0; i < triangles.Length; i += 3)
        {
            int index1 = triangles[i];
            int index2 = triangles[i + 1];
            int index3 = triangles[i + 2];

            ls.Add(new Vector3[]
            {
                uv[index1] * rect + offset,
                uv[index2] * rect + offset,
                uv[index3] * rect + offset
            });


            // 遍历三角形并检查法线方向
            Vector3 normal1 = normals[index1];
            Vector3 normal2 = normals[index2];
            Vector3 normal3 = normals[index3];
            // 检查法线方向是否相似
            if (AreNormalsSimilar(normal1, normal2, normal3))
            {
                //    Debug.Log($"Triangle:[{i},{i + 1},{i + 2}]  belongs to the same face.  ==> {normal1}");
                if (!groupDic.ContainsKey(normal1))
                {
                    groupDic[normal1] = new List<int[]>();
                }

                groupDic[normal1].Add(new int[]
                {
                    index1,
                    index2,
                    index3
                });
            }
            else
            {
                nonGroupLs.Add(new int[]
                {
                    index1,
                    index2,
                    index3
                });
            }
        }

        for (int i = 0; i < nonGroupLs.Count; i++)
        {
            List<Vector2> uvpos = new List<Vector2>();
            for (int j = 0; j < nonGroupLs[i].Length; j++)
            {
                var uvindex = nonGroupLs[i][j];
                uvpos.Add(uv[uvindex] * rect );
            }

            var tf = GenGraph(uvpos, nonGroupLs[i].ToList());
        }

        //判断相邻两个三角形是否在同一个面
        foreach (var item in groupDic)
        {
            List<int[]> arr = item.Value;
            List<List<int>> groups = new List<List<int>>();
            bool isFrist = false;
            for (int i = 0; i < arr.Count; i++)
            {
                var temp2 = arr[0];
                if (i < arr.Count - 1)
                {
                    temp2 = arr[i + 1];
                }
                else
                {
                    if (isFrist)
                    {
                        break;
                    }
                }

                if (CheckSuerface(arr[i], temp2))
                {
                    if (i == 0) isFrist = true;
                    var group = new List<int>();
                    group.AddRange(arr[i]);
                    group.AddRange(temp2);
                    groups.Add(group);
                    if (i < arr.Count - 2)
                    {
                        i += 1;
                    }
                }
                else
                {
                    groups.Add(arr[i].ToList());
                }
            }

            //  Debug.Log($"groups.count:{groups.Count}");
            for (int i = 0; i < groups.Count; i++)
            {
                var group = groups[i];
                List<Vector2> uvpos = new List<Vector2>();
                for (int j = 0; j < group.Count; j++)
                {
                    uvpos.Add(uv[group[j]] * rect );
                }

                var tf = GenGraph(uvpos, group);
            }
        }
    }

    private bool CheckSuerface(int[] triangle1, int[] triangle2)
    {
        byte amount = 0;
        for (byte i = 0; i < 3; i++)
        {
            byte count = 0;
            for (byte j = 0; j < 3; j++)
            {
                if (triangle1[i] == triangle2[j])
                {
                    count++;
                }
            }

            if (count == 1)
            {
                amount++;
            }
        }

        return amount == 2;
    }

    private Transform GenGraph(List<Vector2> uvs, List<int> groups)
    {
        GameObject item;
        if (cacheItems.Count > 0)
        {
            item = cacheItems[0];
            cacheItems.RemoveAt(0);
        }
        else
        {
            item = GameObject.Instantiate(parefab);
        }

        item.transform.SetParent(parent);
        var uvRect = item.GetComponent<UVRect>();

        for (int i = 0; i < uvs.Count; i++)
        {
            uvRect.Add(uvs[i], groups[i]);
        }

        uvRect.Done();

        var tf = item.transform;
        tf.localPosition = Vector3.zero;
        items.Add(item);
        // tf.name = i.ToString();
        return tf;
    }

    public float dotProductThreshold = 0.99f; // 调整此值以控制相似性的阈值

    private bool AreNormalsSimilar(Vector3 normal1, Vector3 normal2, Vector3 normal3)
    {
        // 比较法线方向是否相似，可以使用Dot Product或Angle等方法
        // 这里使用Dot Product进行简单比较
        float dotProduct = Vector3.Dot(normal1.normalized, normal2.normalized);


        return dotProduct >= dotProductThreshold;
    }

    private bool AreVerticesShared(int index1, int index2, int index3, int[] triangles)
    {
        // 检查每个三角形的顶点索引是否共享
        int sharedCount = 0;

        for (int i = 0; i < triangles.Length; i += 3)
        {
            if (triangles[i] == index1 || triangles[i] == index2 || triangles[i] == index3)
            {
                sharedCount++;
            }
        }

        return sharedCount == 4;
    }

    /*********************/
    public Vector2[] newUv;

    public void Save(List<UVInfo> ls)
    {
        var meshfilter = tempgo.GetComponent<MeshFilter>();
        newUv = new Vector2[meshfilter.sharedMesh.uv.Length];
        for (int i = 0; i < ls.Count; i++)
        {
            newUv[ls[i].index] = ls[i].uv * 0.01f;
        }


        meshfilter.sharedMesh.uv = newUv;
    }

    /************gl 绘制**************/

    void OnRenderObject()
    {
        for (int i = 0; i < ls.Count; i++)
        {
            var arr = ls[i];
            DrawSingleLine(arr[0], arr[1]);
            DrawSingleLine(arr[1], arr[2]);
            DrawSingleLine(arr[2], arr[0]);
        }
    }

    void DrawScreenSingleLine(Vector3 start, Vector3 end)
    {
        // Vector3 start = Vector3.zero;
        // Vector3 end = new Vector3(0.2f, 0.7f, 0);
        GL.LoadOrtho(); //屏幕空间，圆心为屏幕左下角，屏幕区域{(0,1), (0,1)}
        GL.Begin(GL.LINES);
        GL.Color(Color.red);
        GL.Vertex(start);
        GL.Vertex(end);
        GL.End();
    }

    void DrawSingleLine(Vector3 start, Vector3 end)
    {
        GL.Begin(GL.LINES);
        GL.Color(Color.white);
        GL.Vertex(start);
        GL.Vertex(end);
        GL.End();
    }
}